﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJ.Data;

namespace PJ.Business
{
    /// <summary>
    /// EntityService class
    /// </summary>
    /// <typeparam name="TIItem">Object to serve type</typeparam>
    /// <typeparam name="OD">Inner data object type</typeparam>
    /// <typeparam name="ODP">Inner data object provider type</typeparam>
    public abstract class ItemService<TIItem, OD, ODP> : EntityService<TIItem, OD, ODP>, IItemService<TIItem>
        where TIItem : class, IItem
        where OD : class, IItemData
        where ODP : class, IItemProvider<OD>
    {
        public ItemService(ODP dataService)
            : base(dataService)
        {
        }

        /// <summary>
        /// Gets the item
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the item with the given name does not exist.</exception>
        IItem IItemService.GetByName(string name)
        {
            return GetByName(name);
        }

        /// <summary>
        /// Gets the item from cache first. If not found in cache, gets the item from provider.
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the item with the given name does not exist.</exception>
        IItem IItemService.CachedGetByName(string name)
        {
            return CachedGetByName(name);
        }

        /// <summary>
        /// Finds the item
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        IItem IItemService.FindByName(string name)
        {
            return FindByName(name);
        }

        /// <summary>
        /// Finds the item from cache first. If not found in cache, finds the item from provider.
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        IEntity IItemService.CachedFindByName(string name)
        {
            return CachedFindByName(name);
        }

        /// <summary>
        /// Searchs the Item that match the given criteria
        /// </summary>
        /// <param name="searchText">search criteria</param>
        /// <returns>Collection of Item global ids</returns>
        /// <exception cref="ArgumentNullException">If <paramref cref="searchText"/> is <see langref="null"/> or empty.</exception>
        public IEnumerable<string> Search(string searchText)
        {
            return DataService.Search(searchText);
        }


        /// <summary>
        /// Gets the item
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the item with the given name does not exist.</exception>
        public TIItem GetByName(string name)
        {
            return CreateNewItem(DataService.GetByName(name));
        }


        /// <summary>
        /// Gets the item from cache first. If not found in cache, gets the item from provider.
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the item with the given name does not exist.</exception>
        public TIItem CachedGetByName(string name)
        {
            return CreateNewItem(DataService.CachedGetByName(name));
        }


        /// <summary>
        /// Finds the item
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        public TIItem FindByName(string name)
        {
            return CreateNewItem(DataService.FindByName(name));
        }


        /// <summary>
        /// Finds the item from cache first. If not found in cache, finds the item from provider.
        /// </summary>
        /// <param name="name">Item name</param>
        /// <returns>The item instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langref="null"/> or empty.</exception>
        public TIItem CachedFindByName(string name)
        {
            return CreateNewItem(DataService.CachedFindByName(name));
        }

    }

}

